package hackTest;

import javax.script.*;

public class ScriptAttack {
    public static void main(String[] args) throws ScriptException, NoSuchMethodException {
        //通过脚本注入的方式，读取java静态变量对象的值，也可以导入类从而实现java方法。
        String sd = "heheda');var x = 100;var out='';print(x);print(user.getName());var fimport = new JavaImporter(Packages.hackTest.Content);" +
                "with(fimport){" +
                "print(Content.s);out = Content.s};" +
                "function helloName(name){print(name+' hello')} " +
                "var obj = new Object(); obj.helloName=function(name){print('hello '+name)};" +
                "function run(){print('run call')}" +
                "var obj1 = new Object(); obj.run=function(){print('run call1')};" +
                "function getUsername(){print('getUsername call')}" +
                "function setUserName(name){print(name+' had set')}" +
                "//";
        ScriptEngineManager scriptEngineManager =new ScriptEngineManager();

        ScriptEngine scriptEngine =scriptEngineManager.getEngineByName("javascript");
        //====================绑定对象
        Bindings bindings = scriptEngineManager.getBindings();
        User user = new User();
        user.setName("gaugua");
        bindings.put("user",user);
        scriptEngine.eval("print('"+sd+"')");
        //=====================获取js中的变量
        System.out.println(scriptEngine.get("out"));
        //=====================调用方法
        Invocable invocable = (Invocable) scriptEngine;
        invocable.invokeFunction("helloName","alexnine");
        Object obj = scriptEngine.get("obj");
        invocable.invokeMethod(obj,"helloName","olive");

        //=====================通过脚本实现java接口 类似于动态代理 生成一个代理类
        Runnable runnable = invocable.getInterface(Runnable.class);
        runnable.run();
        Object obj1 = scriptEngine.get("obj");
        Runnable runnable1 = invocable.getInterface(obj1,Runnable.class);
        runnable1.run();
        UserInterface userInterface = invocable.getInterface(UserInterface.class);
        userInterface.getUsername();
        userInterface.setUserName("wxqdoit");

        multiScopesRun();
    }

    //===========脚本的多个变量范围测试
    private static void multiScopesRun() throws ScriptException {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");
        engine.put("x", "hello");
        //这种是使用默认的ScriptContext
        engine.eval("print(x);");

        // Now, pass a different script context
        ScriptContext newContext = new SimpleScriptContext();
        Bindings engineScope = newContext.getBindings(ScriptContext.ENGINE_SCOPE);

        // add new variable "x" to the new engineScope
        engineScope.put("x", "world");
        // execute the same script - but this time pass a different script context
        engine.eval("print(x);", newContext);
        // the above line prints "world"
    }
}
